package com.itcam.thread_;

/**
 * Author:Cammy.Wu
 * Description:三条线程通信
 */

public class CorrespondenceDemo02 {
    /**
     * 问题：sleep方法和wait方法的区别？
     * 回答：
     * sleep方法是线程休眠，时间到了自动醒来，sleep方法在休眠的时候，不会释放锁
     * wait方法是线程等待，需要由其他线程进行notify唤醒，wait方法在等待期间，会释放锁
     */
    public static void main(String[] args) {
        Printer2 p2 = new Printer2();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    synchronized (Printer2.class) {
                        try {
                            p2.print1();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    synchronized (Printer2.class) {
                        try {
                            p2.print2();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    synchronized (Printer2.class) {
                        try {
                            p2.print3();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }).start();
    }
}

/**
 * void wait(); 使当前线程等待
 * void notify(); 随机唤醒单个等待线程
 * void notifyAll(); 唤醒所有线程（但是相当于有三个保安上班，每次到换班的时间把三个保安叫过来问现在谁上班，影响效率）
 */
class Printer2 {
    int flag = 1;

    public void print1() throws InterruptedException {

        if (flag != 1) {
            // 线程1等待
            Printer1.class.wait();
        }

        System.out.print("指");
        System.out.print("环");
        System.out.print("上");
        System.out.print("铭");
        System.out.print("记");
        System.out.print("着");
        System.out.print("我");
        System.out.print("们");
        System.out.print("的");
        System.out.print("光");
        System.out.print("阴");
        System.out.println();

        flag = 2;
        // 唤醒线程2
//        Printer1.class.notify();
        Printer1.class.notifyAll();
    }

    public void print2() throws InterruptedException {

        if (flag != 2) {
            // 线程2等待
            Printer1.class.wait();
        }

        System.out.print("雅");
        System.out.print("俗");
        System.out.print("共");
        System.out.print("赏");
        System.out.println();

        flag = 3;
        // 唤醒线程3
//        Printer1.class.notify();
        Printer1.class.notifyAll();
    }

    public void print3() throws InterruptedException {

        if (flag != 3) {
            // 线程3等待
            Printer1.class.wait();
        }

        System.out.print("狗");
        System.out.print("都");
        System.out.print("不");
        System.out.print("看");
        System.out.println();

        flag = 1;
        // 唤醒线程1
//        Printer1.class.notify();
        Printer1.class.notifyAll();
    }
}
